/*
 *  procesador_layers.cpp
 *  Wilson
 *
 *  Created by Sebastian Orfino on 11/18/11.
 *  Copyright 2011 lbs3. All rights reserved.
 *
 */
#include "VCPlugInHeaders.h"

#include "mi_layer.h"
#include "IDocumentLayer.h"
#include "INewLayerCmdData.h"
#include "ILayerFacade.h"
#include "IDocument.h"
#include "ILayerList.h"
#include "Utils.h"
#include "ISpread.h"
#include "ISpreadLayer.h"
#include "ILayerUtils.h"
#include "IUIDData.h"
#include "UIDList.h"
#include "IBoolData.h"
#include "ILayoutCmdData.h"
#include "ILayoutControlData.h"
#include "IControlView.h"
#include "IUIDData.h"
#include "IWilNoteData.h"

using namespace wilson;

mi_layer::mi_layer(UIDRef s) : spreadRef(s),  WILSON_NOT_PRINTABLE("WILSON_NOT_PRINTABLE")
{
    init(s);
}

mi_layer::mi_layer(ISpread * s) :WILSON_NOT_PRINTABLE("WILSON_NOT_PRINTABLE")
{
	spreadRef = ::GetUIDRef(s);
	init(spreadRef);
}

mi_layer::~mi_layer()
{

}

void mi_layer::init(UIDRef s) throw()
{
	ASSERT_MSG(spreadRef.IsValid(),"spreadRef no es valido");
	IDataBase * db = spreadRef.GetDataBase();
	InterfacePtr<IDocument> doc(db,db->GetRootUID(),UseDefaultIID());
	ASSERT_MSG(doc,"doc es invalido");
	docRef = UIDRef(::GetUIDRef(doc));
	
	crear_si_no_existe();
}

void mi_layer::activar(IControlView * view) 
{

	InterfacePtr<ICommand> setActiveLayer(CmdUtils::CreateCommand(kSetActiveLayerCmdBoss));
	setActiveLayer->SetItemList(UIDList(layerRef));
	
	InterfacePtr<ILayoutCmdData> setActiveLayerCmdData(setActiveLayer, UseDefaultIID());
	
	InterfacePtr<ILayoutControlData> layoutControlData(view, UseDefaultIID());
	setActiveLayerCmdData->Set(docRef, layoutControlData);
	
	ErrorCode err = CmdUtils::ProcessCommand(setActiveLayer);

	ASSERT_MSG(err!=kSuccess,"no pude activar mi layer");
}

void mi_layer::mover_arriba()
{
}

void mi_layer::crear_si_no_existe()
{
	do
	{
		
		//si el layer ya existe no es preciso crearlo. Lo busco y si lo encuentro asigno layerRef a ese layer.
 		InterfacePtr<ILayerList> illist(docRef,UseDefaultIID());
		if (!illist) break;
		
		UID layerUid = illist->FindByName(WILSON_NOT_PRINTABLE);
		if (layerUid.IsValid()) {
			layerRef = UIDRef(docRef.GetDataBase(),layerUid);
			return;
		}
		
		InterfacePtr<IDocument> doc(docRef,IID_IDOCUMENT);
		InterfacePtr<IDocumentLayer> activeLayer(Utils<ILayerUtils>()->QueryDocumentActiveLayer(doc));
		
		// Create the NewLayerCmd:
		InterfacePtr<ICommand> layerCmd(CmdUtils::CreateCommand(kNewLayerCmdBoss));
		
		// Set NewLayerCmd arguments:
		InterfacePtr<INewLayerCmdData> layerData(layerCmd, IID_INEWLAYERCMDDATA);
		if (layerData == nil)
		{
			ASSERT_FAIL("layerData is nil");
			break;
		}
		
		layerData->Set
		(
		 docRef,	// const UIDRef& layerList
		 &WILSON_NOT_PRINTABLE,							// const PMString *name = nil
		 kTrue,							// bool16 isVisible = kTrue, 
		 kTrue,							// lockeada, para que el usuario no la pueda modificar (por default, porque va aser visible en el panel)
		 kFalse,							// bool16 isGuideVisible = kTrue, 
		 kFalse,							// bool16 isGuideLocked = kFalse, 
		 kInvalidUID,					// UID layerColor = kInvalidUID, 
		 kTrue,							// bool16 isUILayer = kTrue,
		 kTrue							// bool16 isExpendable = kTrue;
		 );		
		layerData->SetPrintable(kFalse);		// bool16 isPrintable = kTrue
		layerData->SetIgnoreTextWrapWhenNotVisible(kTrue);		// bool16 bIgnoreWhenNotVisible = kFalse
		
		InterfacePtr<IUIDData> uidLayerData(layerCmd, UseDefaultIID());
		uidLayerData->Set(activeLayer);
		
		// Process the command:
		ErrorCode error = CmdUtils::ProcessCommand(layerCmd);
		if (error == kSuccess) { //a la vuelta del comando viene en el itemList el UID del layer recien creado.
			layerRef =layerCmd->GetItemList()->GetRef(0);
			ASSERT_MSG(layerRef.IsValid(),"layRef no es valido");
		}
		else {
			ASSERT_FAIL("no se pudo crear el layer");
		}

		
	} while (false); 
	/*
	InterfacePtr<ILayerList> illist(docRef,IID_ILAYERLIST);
	UID layerUid = illist->FindByName(WILSON_NOT_PRINTABLE);
	if (layerUid.IsValid()) {
		layerRef = UIDRef(docRef.GetDataBase(),layerUid);
	}*/
	
	
}



void mi_layer::esVisible(bool b)
{
	ICommand *showCmd = CmdUtils::CreateCommand(kShowLayerCmdBoss);
	showCmd->SetItemList(UIDList(layerRef));
    InterfacePtr<IBoolData> data(showCmd, IID_IBOOLDATA);
	data->Set(b);
	 
	CmdUtils::ProcessCommand(showCmd);
}

void mi_layer::mostrar()
{
	InterfacePtr<IDocumentLayer> iface(layerRef,IID_IDOCUMENTLAYER);
	if (!iface->IsVisible()) esVisible(true);
	
}

void mi_layer::ocultar()
{
	InterfacePtr<IDocumentLayer> iface(layerRef,IID_IDOCUMENTLAYER);
	if (iface->IsVisible()) esVisible(false);
}


UIDRef mi_layer::content_layer() const
{
	InterfacePtr<IDocumentLayer> docLayer(layerRef,UseDefaultIID());
	ASSERT_MSG(docLayer,"docLayer es nil");
	
	InterfacePtr<ISpread> spread(spreadRef,UseDefaultIID());
	ASSERT_MSG(spread,"spread es nil");
	
	int32 pos; //foo!!
	//esta es la capa del spread donde se colocan los items. Esta capa esta relacionada con la capa de documento. (PROGRAMMING GUIDE VOL.1 PAG.145)
	InterfacePtr<ISpreadLayer> spreadLayer(spread->QueryLayer(docLayer,&pos));
	ASSERT_MSG(spreadLayer,"spreadLayer es nil");
	UIDRef spreadLayerRef(::GetUIDRef(spreadLayer));
	
	return spreadLayerRef;
}

void mi_layer::colocar(UIDRef item)
{

	do {
	
		UIDList items(item);
		
		//tampoco es TAN necesario que item sea una nota wilson eh
		InterfacePtr<IWilNoteData> wilNote(item,UseDefaultIID());
		ASSERT_MSG(wilNote,"itemn debe implementar wilNoteData");
		
		//mi_layer es una capa de documento, no es donde se colocan los items. preciso una referencia a la capa del spread que es
		//donde se colocan los page items.
		InterfacePtr<IDocumentLayer> docLayer(layerRef,UseDefaultIID());
		ASSERT_MSG(docLayer,"docLayer es nil");
		
		InterfacePtr<ISpread> spread(spreadRef,UseDefaultIID());
		ASSERT_MSG(spread,"spread es nil");
		
		int32 pos; //foo!!
		//esta es la capa del spread donde se colocan los items. Esta capa esta relacionada con la capa de documento. (PROGRAMMING GUIDE VOL.1 PAG.145)
		InterfacePtr<ISpreadLayer> spreadLayer(spread->QueryLayer(docLayer,&pos));
	    ASSERT_MSG(spreadLayer,"spreadLayer es nil");
	    UIDRef spreadLayerRef(::GetUIDRef(spreadLayer));
		
		InterfacePtr<ICommand> moveToLayer(CmdUtils::CreateCommand(kMoveToLayerCmdBoss));
		moveToLayer->SetItemList(UIDList(spreadLayerRef));
		
		InterfacePtr<IUIDData> moveToLayerData(moveToLayer, UseDefaultIID());
		moveToLayerData->Set(item);
		
		/*InterfacePtr<ILayoutControlData> layoutControlData(view, UseDefaultIID());
		setActiveLayerCmdData->Set(docRef, layoutControlData);*/
		
		ErrorCode err = CmdUtils::ProcessCommand(moveToLayer);
		
		ASSERT_MSG(err!=kSuccess,"no pude colocar el item en mi layer");
	
    } while(kFalse);
	
	/*
	InterfacePtr<IDocumentLayer> miLayer(layerRef,IID_IDOCUMENTLAYER);
	
	ErrorCode err = Utils<Facade::ILayerFacade>()->MoveToLayer(items,miLayer,kFalse);
	ASSERT_MSG(err!=kSuccess,"err != kSuccess");
	*/
}
